package com.powernode.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.dao.ProdEsDao;
import com.powernode.domain.Prod;
import com.powernode.domain.ProdComm;
import com.powernode.domain.User;
import com.powernode.feign.ProdCommMemberFeign;
import com.powernode.mapper.ProdCommMapper;
import com.powernode.model.ProdEs;
import com.powernode.service.ProdCommService;
import com.powernode.service.ProdService;
import com.powernode.utils.AuthUtil;
import com.powernode.vo.ProdCommOverview;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 内容:
 * 作者: cy
 */
@Service
public class ProdCommServiceImpl extends ServiceImpl<ProdCommMapper, ProdComm> implements ProdCommService {

    @Autowired
    private ProdCommMapper prodCommMapper;

    @Autowired
    private ProdService prodService;

    @Autowired
    private ProdEsDao prodEsDao;

    @Autowired
    private ProdCommMemberFeign prodCommMemberFeign;


    /**
     * 分页查询评论列表
     * 目的 分页查询评论表
     * 1.先判断 到底有没有输入商品的名字进来
     * 2.如果输入了名字 就要先查商品表 按到商品的ids
     * 3.再去分页查询评论表
     * 4.再给评论组装商品的名称
     * 5.返回
     * ------------------- 思考
     * 表的设计就有问题
     * 在设计表的是 要适当的使用反范式 （设计一些冗余字段 方便查询 提供性能）
     * 如果设计冗余字段 就会存在 冗余数据一致性问题
     * 一般冗余字段 可以不做处理  反问 你们怎么处理的？？？？
     * ------------------- 思考
     * 链表查询 都可以实现
     * 互联网公司
     * 传统公司
     * 用代码来做 好维护
     * 很多会写sql 不好维护  代码简洁  sql功力很强
     *
     * @param page
     * @param prodComm
     * @return
     */
    @Override
    public Page<ProdComm> selectProdCommPage(Page<ProdComm> page, ProdComm prodComm) {
        Page<ProdComm> prodCommPage = new Page<>(page.getCurrent(), page.getSize());
        // shopId = 就是超级管理员 第一人
        Long shopId = AuthUtil.getUserIdOrShopId(false);
        // 代码写不到 就硬写 不考虑质量问题
        String prodName = prodComm.getProdName();
        List<Long> prodIds = null;
        if (StringUtils.hasText(prodName)) {
            // 说明传了名字进来
            List<Prod> prodList = prodService.list(new LambdaQueryWrapper<Prod>()
                    .eq(shopId != 1, Prod::getShopId, shopId)
                    .like(Prod::getProdName, prodName)
            );
            if (CollectionUtils.isEmpty(prodList)) {
                // 说明这个名字的商品 不存在
                prodCommPage.setTotal(0L);
                return prodCommPage;
            }
            // 拿到ids
            prodIds = prodList.stream()
                    .map(Prod::getProdId).collect(Collectors.toList());
        }
        prodCommPage = prodCommMapper.selectPage(page, new LambdaQueryWrapper<ProdComm>()
                .eq(shopId != 1, ProdComm::getShopId, shopId)
                .in(!CollectionUtils.isEmpty(prodIds), ProdComm::getProdId, prodIds)
                .eq(!ObjectUtils.isEmpty(prodComm.getStatus()), ProdComm::getStatus, prodComm.getStatus())
        );
        // 组装名字 ....
        List<ProdComm> prodCommList = prodCommPage.getRecords();
        if (!CollectionUtils.isEmpty(prodCommList)) {
            // 说明有评论  又得反向查了  精确查询一次
            List<Long> newProdIds = prodCommList.stream()
                    .map(ProdComm::getProdId)
                    .collect(Collectors.toList());
            // 查询商品表
            List<Prod> prodList = prodService.listByIds(newProdIds);
            // 循环评论集合
            prodCommList.forEach(prodComm1 -> {
                // 过滤出符合条件的商品的对象
                Prod prod1 = prodList.stream().filter(prod -> prod.getProdId().equals(prodComm1.getProdId()))
                        .collect(Collectors.toList())
                        .get(0);
                prodComm1.setProdName(prod1.getProdName());
            });
        }
        return prodCommPage;
    }


    /**
     * 根据商品id查询评论总览
     * 你是想 直接查询这个商品对应的所有评论数据
     * select * from comm where prodId = 1  jvm可能会爆掉的
     * stream().filter
     * 还是发很多sql语句 一次查一种结果
     * select count(id) from comm where prodId = 1 and evalaution = 0
     * select count(id) from comm where prodId = 1 and evalaution = 1
     * select count(id) from comm where prodId = 1 and evalaution = 2
     * <p>
     * 看数据量来判断操作
     * 当数据大的时候 就发小的sql
     *
     * @param prodId
     * @return
     */
    @Override
    public ProdCommOverview selectFrontProdCommOverview(Long prodId) {
        // 组装这个对象
        // 总评数
        Integer allCount = prodCommMapper.selectCount(new LambdaQueryWrapper<ProdComm>()
                .eq(ProdComm::getProdId, prodId)
        );
        ProdEs prodEs = prodEsDao.findById(prodId).get();
        Long praiseNumber = prodEs.getPraiseNumber();
        BigDecimal positiveRating = prodEs.getPositiveRating();
        // 中评 差评 带图
        Integer secondCount = prodCommMapper.selectCount(new LambdaQueryWrapper<ProdComm>()
                .eq(ProdComm::getProdId, prodId)
                .eq(ProdComm::getEvaluate, 1)
        );
        Integer badCount = prodCommMapper.selectCount(new LambdaQueryWrapper<ProdComm>()
                .eq(ProdComm::getProdId, prodId)
                .eq(ProdComm::getEvaluate, 2)
        );

        Integer picCount = prodCommMapper.selectCount(new LambdaQueryWrapper<ProdComm>()
                .eq(ProdComm::getProdId, prodId)
                .isNotNull(ProdComm::getPics)
        );
        return ProdCommOverview.builder()
                .number(allCount)
                .positiveRating(positiveRating)
                .praiseNumber(praiseNumber.intValue())
                .secondaryNumber(secondCount)
                .negativeNumber(badCount)
                .picNumber(picCount)
                .build();
    }

    /**
     * 根据商品id分页查询评论信息
     *
     * @param prodId
     * @return
     */
    @Override
    public Page<ProdComm> selectFrontProdCommPageByProdId(Page<ProdComm> page, Long prodId) {
        Page<ProdComm> prodCommPage = prodCommMapper.selectPage(page, new LambdaQueryWrapper<ProdComm>()
                .eq(ProdComm::getProdId, prodId)
                .eq(ProdComm::getStatus, 1)
                .orderByDesc(ProdComm::getScore, ProdComm::getRecTime)
        );
        List<ProdComm> prodCommList = prodCommPage.getRecords();
        if (CollectionUtils.isEmpty(prodCommList)) {
            return prodCommPage;
        }
        // 拿到用户的ids
        List<String> openIds = prodCommList.stream()
                .map(ProdComm::getUserId)
                .collect(Collectors.toList());
        // 需要去远程调用 用户模块 查询用户的头像和昵称
        List<User> userList = prodCommMemberFeign.getUsersByOpenIds(openIds);
        if (!CollectionUtils.isEmpty(userList)) {
            // 组装
            // 这里将名称处理一下 脱敏处理
            prodCommList.forEach(prodComm -> {
                User user1 = userList.stream()
                        .filter(user -> user.getUserId().equals(prodComm.getUserId()))
                        .collect(Collectors.toList())
                        .get(0);
                prodComm.setPic(user1.getPic());
                String nickName = user1.getNickName();
                StringBuilder sb = new StringBuilder(nickName);
                sb.replace(0, sb.length() - 1, "***");
                prodComm.setNickName(sb.toString());

            });
        }
        return prodCommPage;
    }
}
